package com.haina.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haina.shop.constant.MessageConstant;
import com.haina.shop.context.BaseContext;
import com.haina.shop.domain.Basket;
import com.haina.shop.domain.Prod;
import com.haina.shop.domain.ShopDetail;
import com.haina.shop.dto.ChangeItemDTO;
import com.haina.shop.dto.DiscountDto;
import com.haina.shop.dto.ShopCartItemDiscountDto;
import com.haina.shop.dto.ShopCartItemDto;
import com.haina.shop.mapper.ProdMapper;
import com.haina.shop.mapper.ShopDetailMapper;
import com.haina.shop.mapper.SkuMapper;
import com.haina.shop.result.ServiceResult;
import com.haina.shop.service.BasketService;
import com.haina.shop.mapper.BasketMapper;
import com.haina.shop.vo.ShoppingCartTotalVO;
import com.haina.shop.vo.ShoppingCartVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 48077
* @description 针对表【tz_basket(购物车)】的数据库操作Service实现
* @createDate 2024-07-31 18:34:29
*/
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket>
    implements BasketService{
    @Autowired
    private BasketMapper mapper;
    @Autowired
    private ShopDetailMapper shopDetailMapper;
    @Autowired
    private ProdMapper prodMapper;
    @Autowired
    private SkuMapper skuMapper;
    /**
     * 获取当前用户购物车商品数量
     */
    @Override
    public ServiceResult<Long> getShoppingCartCount(){
        int count=0;
        Long userId = BaseContext.getCurrentId();
        List<Basket> basketList=mapper.selectByUserId(String.valueOf(userId));
        if(basketList!=null&&!basketList.isEmpty()){//需要判断当前用户购物车是否为空
            for (Basket basket : basketList) {
                //获取每个商品的数量
                count+=basket.getBasketCount();
            }
        }

        return ServiceResult.success(Long.valueOf(count));
    }
    /**
     * 获取当前用户的购物车信息
     */
    @Override
    public ServiceResult<List<ShoppingCartVO>> getInfoByUserId() {
       //获取当前用户的id
        Long userId = BaseContext.getCurrentId();
       //根据当前用户id查询购物车里的所有数据
        LambdaQueryWrapper<Basket> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Basket::getUserId,userId);
        List<Basket> basketList = list(wrapper);
        //根据购物车里面的shopId进行分类
        Map<Long, List<Basket>> map = basketList.stream()
                .collect(Collectors.groupingBy(Basket::getShopId));
        List<ShoppingCartVO> shoppingCartVOS=new ArrayList<>();
       //对Map集合进行遍历
        for (Map.Entry<Long, List<Basket>> entry : map.entrySet()) {
            //获取shopId
            Long shopId = entry.getKey();
            //根据shopId查询shopName
            LambdaQueryWrapper<ShopDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ShopDetail::getShopId,shopId);
            ShopDetail shopDetail = shopDetailMapper.selectOne(queryWrapper);
            ShoppingCartVO shoppingCartVO = new ShoppingCartVO();
            shoppingCartVO.setShopId(shopId);
            shoppingCartVO.setShopName(shopDetail.getShopName());
            List<Basket> baskets = entry.getValue();
            List<ShopCartItemDiscountDto> shopCartItemDiscountDtos=new ArrayList<>();
            //basekets根据discountId进行分类
            Map<Long, List<Basket>> collect = baskets.stream().collect(
                    Collectors.groupingBy(Basket::getDiscountId)
            );
            for (Map.Entry<Long, List<Basket>> longListEntry : collect.entrySet()) {
                Long discountId = longListEntry.getKey();
                List<Basket> baskets1 = longListEntry.getValue();
                ShopCartItemDiscountDto shopCartItemDiscountDto = new ShopCartItemDiscountDto();
                List<ShopCartItemDto> shopCartItemDtos=new ArrayList<>();
                for (Basket basket : baskets1) {
                    ShopCartItemDto dto = getDTO(basket);
                    shopCartItemDtos.add(dto);
                }
                shopCartItemDiscountDto.setShopCartItems(shopCartItemDtos);
                shopCartItemDiscountDtos.add(shopCartItemDiscountDto);
            }
            shoppingCartVO.setShopCartItemDiscounts(shopCartItemDiscountDtos);
            shoppingCartVOS.add(shoppingCartVO);

        }

        return ServiceResult.success(shoppingCartVOS);
    }
    /**
     * 获取选中购物项总计、选中的商品数量,参数为购物车id数组
     */
    @Override
    public ServiceResult<ShoppingCartTotalVO> getTotalPay() {
        ShoppingCartTotalVO totalVO = new ShoppingCartTotalVO();
        ServiceResult<Long> shoppingCartCount = getShoppingCartCount();
        Long count = shoppingCartCount.getData();
        totalVO.setCount(count);
        //获取当前用户的id
        Long userId = BaseContext.getCurrentId();
        //根据当前用户id查询购物车里的所有数据
        LambdaQueryWrapper<Basket> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Basket::getUserId,userId);
        List<Basket> basketList = list(wrapper);
        if(basketList!=null&& !basketList.isEmpty()){//需要判断当前用户的购物车是否为null
            //获取所有的prodId
            List<Long> prodIdList = basketList.stream().map(Basket::getProdId)
                    .collect(Collectors.toList());
            //将所有的prodId查出来
            LambdaQueryWrapper<Prod> wrapper1 = new LambdaQueryWrapper<>();
            //范围查询  不能为等值查询
            wrapper1.in(prodIdList!=null,Prod::getProdId,prodIdList);
            List<Prod> prodList = prodMapper.selectList(wrapper1);
            double totalMoney=0.0;
            double finalMoney=0.0;
            for (Prod prod : prodList) {
                //获取prod的原始价格和打折后价格，以及购物车里面的商品数量
                BigDecimal oriPrice = prod.getOriPrice();
                BigDecimal price = prod.getPrice();
                totalMoney+=oriPrice.doubleValue()*count;
                finalMoney+=price.doubleValue()*count;
            }
            totalVO.setTotalMoney(totalMoney);
            totalVO.setFinalMoney(finalMoney);
            totalVO.setSubtractMoney(totalMoney-finalMoney);
        }else{
            totalVO.setTotalMoney(0.0);
            totalVO.setFinalMoney(0.0);
            totalVO.setSubtractMoney(0.0);
        }
        return ServiceResult.success(totalVO);
    }
    /**
     * 通过商品id(prodId)、skuId、店铺Id(shopId),添加/修改用户购物车商品，
     * 并传入改变的商品个数(count)，当count为正值时，
     * 增加商品数量，当count为负值时，将减去商品的数量，
     * 当最终count值小于0时，会将商品从购物车里面删除
     * @param dto
     */
    @Override
    @Transactional
    public ServiceResult changeItem(ChangeItemDTO dto){
        Long prodId = dto.getProdId();
        Long skuId = dto.getSkuId();
        Long shopId = dto.getShopId();
        //根据basketId是否为null判断是添加还是修改购物车
        if(dto.getBasketId()==null){
            //为null为修改
            //条件封装
            LambdaQueryWrapper<Basket> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Basket::getProdId,prodId)
                    .eq(Basket::getShopId,shopId)
                    .eq(Basket::getSkuId,skuId);
            //查询数据
            Basket basket = mapper.selectOne(wrapper);
            //该商品的原始数量
            Integer basketCount = basket.getBasketCount();
            //直接加上count即可，加完需要判断数量是否大于0
            basketCount+=dto.getCount();
            if(basketCount<=0){
                //会将商品从购物车里面删除
                mapper.delete(wrapper);
            }else{
                //修改商品的数量
                basket.setBasketCount(basketCount);
                LambdaUpdateWrapper<Basket> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(Basket::getProdId,prodId)
                        .eq(Basket::getShopId,shopId)
                        .eq(Basket::getSkuId,skuId);
                mapper.update(basket,updateWrapper);
            }
        }else{
            //判断商品的库存是否充足
            Prod prod = prodMapper.selectById(prodId);
            if(prod.getTotalStocks()<=0){
                //库存不充足
                return ServiceResult.error(MessageConstant.ERROR_CODE,prod.getProdName()+MessageConstant.STOCKS_EMPTY);
            }else{
                //添加购物车
                Basket basket = new Basket(prod.getShopId(), prodId, skuId, String.valueOf(BaseContext.getCurrentId()), dto.getCount(), new Date(),
                        1L, null);
                mapper.insert(basket);
            }

        }
        return ServiceResult.success();
    }
    /**
     * 通过购物车id删除用户购物车物品
     * @param integers
     */
    @Override
    public ServiceResult deleteItem(List<Long> integers) {
        LambdaQueryWrapper<Basket> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Basket::getBasketId,integers);
        int rows = mapper.delete(wrapper);
        if(rows>0){
            return ServiceResult.success("删除成功");
        }else{
            return ServiceResult.error(MessageConstant.ERROR_CODE,"删除失败");
        }

    }

    //entity->ShopCartItemDto
    public ShopCartItemDto getDTO(Basket basket){
        List<DiscountDto> objects = new ArrayList<>();
        //获取prodId
        Long prodId = basket.getProdId();
        //根据proId查询数据
        Prod prod=prodMapper.getById(prodId);
        //根据shopId查询shopName
        LambdaQueryWrapper<ShopDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopDetail::getShopId,prod.getShopId());
        ShopDetail shopDetail = shopDetailMapper.selectOne(queryWrapper);
        //根据skuId查询skuName
        String skuName=skuMapper.selectNameById(basket.getSkuId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return new ShopCartItemDto(
           null,sdf.format(basket.getBasketDate()),basket.getBasketId(),basket.getDiscountId(),
                objects,null,prod.getOriPrice().doubleValue(),
                prod.getPic(),prod.getPrice().doubleValue(),
                basket.getBasketCount(),prodId,prod.getProdName(),
                prod.getPrice().doubleValue(),null,prod.getShopId(),
                shopDetail.getShopName(), basket.getSkuId(),skuName
        );
    }
}




